package com.alvinlkk.basic.chapter21.waxomatic2;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class Car {
    
    private Lock lock = new ReentrantLock();
    
    private Condition condition = lock.newCondition();
    
    private boolean waxOn = false;   //是否打蜡了
    
    public void wax() {  //打蜡
        lock.lock();
        try {
            waxOn = true;
            condition.signalAll();
        } finally {
            lock.unlock();
        }
        
    }
    
    public void buffed() {  //抛光
        
        lock.lock();
        try {
            waxOn = false;
            condition.signalAll();
        } finally {
            lock.unlock();
        }
    }
    
    public void waitingForWaxing() throws InterruptedException {  //等待打蜡
        lock.lock();
        try {
            while(waxOn == false) {
                condition.await();
            } 
        } finally {
            lock.unlock();
        }
        
    }
    
    public void waitingForBuffing() throws InterruptedException {
        lock.lock();
        try {
            while(waxOn == true) {
                condition.await();
            } 
        } finally {
            lock.unlock();
        }
    }
}

class WaxOn implements Runnable {
    
    private Car car;
    
    public WaxOn(Car car) {
        this.car = car;
    }
    
    @Override
    public void run() {
        while(!Thread.interrupted()) {
            System.out.println("WAX on ....");
            try {
                TimeUnit.SECONDS.sleep(1);
                car.wax();
                car.waitingForBuffing();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

 class WaxOff implements Runnable {
     
     private Car car;
     
     public WaxOff(Car car) {
         this.car = car;
     }
     
    @Override
    public void run() {
        while (!Thread.interrupted()) {
            try {
                car.waitingForWaxing();
                System.out.println("Wax OFF!");
                TimeUnit.SECONDS.sleep(1);
                car.buffed();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            
        }
    }
     
 }

public class WaxOMatic2 {
    public static void main(String[] args) throws InterruptedException {
        Car car = new Car();
        ExecutorService exec = Executors.newCachedThreadPool();
        exec.execute(new WaxOff(car));
        exec.execute(new WaxOn(car));
        TimeUnit.SECONDS.sleep(5);
        exec.shutdownNow();
    }
}
